package demoMod.invincibleOne.powers;

import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.megacrit.cardcrawl.actions.AbstractGameAction;
import com.megacrit.cardcrawl.actions.animations.VFXAction;
import com.megacrit.cardcrawl.actions.common.DamageAction;
import com.megacrit.cardcrawl.actions.common.ReducePowerAction;
import com.megacrit.cardcrawl.actions.common.RemoveSpecificPowerAction;
import com.megacrit.cardcrawl.cards.AbstractCard;
import com.megacrit.cardcrawl.cards.DamageInfo;
import com.megacrit.cardcrawl.characters.AbstractPlayer;
import com.megacrit.cardcrawl.core.AbstractCreature;
import com.megacrit.cardcrawl.core.CardCrawlGame;
import com.megacrit.cardcrawl.dungeons.AbstractDungeon;
import com.megacrit.cardcrawl.helpers.ImageMaster;
import com.megacrit.cardcrawl.localization.PowerStrings;
import com.megacrit.cardcrawl.powers.AbstractPower;
import com.megacrit.cardcrawl.vfx.combat.ExplosionSmallEffect;
import demoMod.invincibleOne.InvincibleOneMod;
import demoMod.invincibleOne.interfaces.OilApplyHook;
import demoMod.invincibleOne.interfaces.OilExplodeHook;

import java.util.stream.Collectors;

public class OilStainedPower extends AbstractPower {
    public static final String POWER_ID = InvincibleOneMod.makeID("OilStainedPower");
    private static final PowerStrings powerStrings = CardCrawlGame.languagePack.getPowerStrings(POWER_ID);
    public static final String NAME = powerStrings.NAME;
    public static final String[] DESC = powerStrings.DESCRIPTIONS;

    public OilStainedPower(AbstractCreature owner, int amount) {
        this.owner = owner;
        this.ID = POWER_ID;
        this.name = NAME;
        this.amount = amount;
        String path128 = InvincibleOneMod.getResourcePath("powers/128/Oiled.png");
        String path48 = InvincibleOneMod.getResourcePath("powers/48/Oiled.png");
        this.region128 = new TextureAtlas.AtlasRegion(ImageMaster.loadImage(path128), 0, 0, 84, 84);
        this.region48 = new TextureAtlas.AtlasRegion(ImageMaster.loadImage(path48), 0, 0, 32, 32);
        this.updateDescription();
        this.type = PowerType.DEBUFF;
    }

    @Override
    public void onInitialApplication() {
        for (AbstractCard card : AbstractDungeon.player.drawPile.group.stream().filter(c -> c instanceof OilApplyHook).collect(Collectors.toList())) {
            this.amount = ((OilApplyHook) card).onApplyOil(this.owner, this.amount);
        }
        for (AbstractPower power : AbstractDungeon.player.powers.stream().filter(p -> p instanceof OilApplyHook).collect(Collectors.toList())) {
            this.amount = ((OilApplyHook) power).onApplyOil(this.owner, this.amount);
        }
    }

    @Override
    public void updateDescription() {
        int explodeAmount = 6;
        for (AbstractPower power : owner.powers.stream().filter(abstractPower -> abstractPower instanceof OilExplodeHook).collect(Collectors.toList())) {
            explodeAmount = ((OilExplodeHook) power).modifyExplodeTriggerAmount(explodeAmount);
        }
        int damageAmount = Math.max(amount, explodeAmount);
        int reduceAmount = Math.max(amount, explodeAmount);
        for (AbstractPower power : owner.powers.stream().filter(abstractPower -> abstractPower instanceof OilExplodeHook).collect(Collectors.toList())) {
            reduceAmount = ((OilExplodeHook) power).reduceExplodeAmount(reduceAmount);
            damageAmount = ((OilExplodeHook) power).modifyExplodeDamage(damageAmount);
        }
        this.description = String.format(DESC[0], explodeAmount, damageAmount, reduceAmount);
    }

    private void checkExplode() {
        int explodeAmount = 6;
        for (AbstractPower power : owner.powers.stream().filter(abstractPower -> abstractPower instanceof OilExplodeHook).collect(Collectors.toList())) {
            explodeAmount = ((OilExplodeHook) power).modifyExplodeTriggerAmount(explodeAmount);
        }
        boolean shouldExplode = true;
        for (AbstractPower power : owner.powers.stream().filter(abstractPower -> abstractPower instanceof OilExplodeHook).collect(Collectors.toList())) {
            shouldExplode = shouldExplode && ((OilExplodeHook) power).shouldExplode(owner);
        }
        for (AbstractPower power : AbstractDungeon.player.powers.stream().filter(abstractPower -> abstractPower instanceof OilExplodeHook).collect(Collectors.toList())) {
            shouldExplode = shouldExplode && ((OilExplodeHook) power).shouldExplode(owner);
        }
        if (amount >= explodeAmount && shouldExplode) {
            this.flash();
            int reduceAmount = amount;
            int damageAmount = amount;
            if (!(owner instanceof AbstractPlayer)) {
                for (AbstractPower power : owner.powers.stream().filter(abstractPower -> abstractPower instanceof OilExplodeHook).collect(Collectors.toList())) {
                    reduceAmount = ((OilExplodeHook) power).reduceExplodeAmount(reduceAmount);
                    damageAmount = ((OilExplodeHook) power).modifyExplodeDamage(damageAmount);
                }
            }
            for (AbstractPower power : AbstractDungeon.player.powers.stream().filter(abstractPower -> abstractPower instanceof OilExplodeHook).collect(Collectors.toList())) {
                reduceAmount = ((OilExplodeHook) power).reduceExplodeAmount(reduceAmount);
                damageAmount = ((OilExplodeHook) power).modifyExplodeDamage(damageAmount);
            }
            addToTop(new ReducePowerAction(owner, owner, POWER_ID, reduceAmount));
            if (owner.hasPower("Metallicize")) {
                if (owner.getPower("Metallicize").amount > damageAmount / 3) {
                    addToTop(new ReducePowerAction(owner, owner, "Metallicize", damageAmount / 3));
                } else {
                    addToTop(new RemoveSpecificPowerAction(owner, owner, "Metallicize"));
                }
            }
            addToTop(new DamageAction(owner, new DamageInfo(owner, damageAmount, DamageInfo.DamageType.THORNS), AbstractGameAction.AttackEffect.FIRE));
            addToTop(new VFXAction(new ExplosionSmallEffect(owner.hb.cX, owner.hb.cY), 0.1F));
        }
    }

    @Override
    public void atEndOfTurn(boolean isPlayer) {
        checkExplode();
    }

    @Override
    public void stackPower(int stackAmount) {
        for (AbstractCard card : AbstractDungeon.player.drawPile.group.stream().filter(c -> c instanceof OilApplyHook).collect(Collectors.toList())) {
            stackAmount = ((OilApplyHook) card).onApplyOil(this.owner, stackAmount);
        }
        for (AbstractPower power : AbstractDungeon.player.powers.stream().filter(p -> p instanceof OilApplyHook).collect(Collectors.toList())) {
            stackAmount = ((OilApplyHook) power).onApplyOil(this.owner, stackAmount);
        }
        super.stackPower(stackAmount);
    }
}
